<template>
  <div class="material-category">
    <div class="page-header">
      <h1>物料分类管理</h1>
      <div class="header-actions">
        <el-button type="primary" @click="showCreateDialog = true">
          <el-icon><Plus /></el-icon>
          新增分类
        </el-button>
        <el-button @click="expandAll">
          <el-icon><Expand /></el-icon>
          展开全部
        </el-button>
        <el-button @click="collapseAll">
          <el-icon><Fold /></el-icon>
          收起全部
        </el-button>
      </div>
    </div>

    <div class="category-container">
      <div class="category-header">
        <div class="search-section">
          <el-input
            v-model="searchText"
            placeholder="搜索分类名称或代码"
            style="width: 300px"
            clearable
            @input="handleSearch"
          >
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
          </el-input>
          <el-switch
            v-model="showActiveOnly"
            active-text="仅显示启用"
            inactive-text="显示全部"
            style="margin-left: 20px"
          />
        </div>
        
        <div class="stats-section">
          <el-statistic title="总分类数" :value="stats.total_categories" />
          <el-statistic title="启用分类" :value="stats.active_categories" />
          <el-statistic title="最大层级" :value="stats.max_level" />
          <el-statistic title="有物料分类" :value="stats.categories_with_materials" />
        </div>
      </div>

      <div class="category-tree">
        <el-tree
          ref="categoryTreeRef"
          :data="filteredTreeData"
          :props="treeProps"
          node-key="id"
          :expand-on-click-node="false"
          :render-content="renderTreeNode"
          draggable
          @node-drop="handleNodeDrop"
          :allow-drop="allowDrop"
          :allow-drag="allowDrag"
        />
      </div>
    </div>

    <!-- 创建/编辑分类对话框 -->
    <el-dialog
      v-model="showCreateDialog"
      :title="editingCategory ? '编辑分类' : '新增分类'"
      width="600px"
    >
      <el-form :model="categoryForm" :rules="categoryRules" ref="categoryFormRef" label-width="100px">
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="categoryForm.name" />
        </el-form-item>
        <el-form-item label="分类代码" prop="code">
          <el-input v-model="categoryForm.code" @blur="checkCodeUnique" />
          <div v-if="codeCheckResult" class="code-check-result">
            <el-text :type="codeCheckResult.isUnique ? 'success' : 'danger'">
              {{ codeCheckResult.isUnique ? '代码可用' : '代码已存在' }}
            </el-text>
          </div>
        </el-form-item>
        <el-form-item label="父级分类">
          <el-tree-select
            v-model="categoryForm.parent_id"
            :data="parentSelectData"
            :props="treeSelectProps"
            placeholder="选择父级分类（可选）"
            clearable
            check-strictly
            style="width: 100%"
          />
        </el-form-item>
        <el-form-item label="排序">
          <el-input-number v-model="categoryForm.sort_order" :min="0" style="width: 100%" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="categoryForm.description" type="textarea" :rows="3" />
        </el-form-item>
        <el-form-item label="状态">
          <el-switch v-model="categoryForm.is_active" active-text="启用" inactive-text="禁用" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showCreateDialog = false">取消</el-button>
        <el-button type="primary" @click="saveCategory">保存</el-button>
      </template>
    </el-dialog>

    <!-- 分类详情对话框 -->
    <el-dialog v-model="showDetailDialog" title="分类详情" width="800px">
      <div v-if="selectedCategory" class="category-detail">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="分类名称">{{ selectedCategory.name }}</el-descriptions-item>
          <el-descriptions-item label="分类代码">{{ selectedCategory.code }}</el-descriptions-item>
          <el-descriptions-item label="层级">{{ selectedCategory.level }}</el-descriptions-item>
          <el-descriptions-item label="排序">{{ selectedCategory.sort_order }}</el-descriptions-item>
          <el-descriptions-item label="状态">
            <el-tag :type="selectedCategory.is_active ? 'success' : 'danger'">
              {{ selectedCategory.is_active ? '启用' : '禁用' }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="物料数量">{{ selectedCategory.material_count || 0 }}</el-descriptions-item>
          <el-descriptions-item label="创建时间" :span="2">
            {{ formatDate(selectedCategory.created_at) }}
          </el-descriptions-item>
          <el-descriptions-item label="更新时间" :span="2">
            {{ formatDate(selectedCategory.updated_at) }}
          </el-descriptions-item>
          <el-descriptions-item label="描述" :span="2">
            {{ selectedCategory.description || '无' }}
          </el-descriptions-item>
        </el-descriptions>

        <div class="category-path">
          <h4>分类路径</h4>
          <el-breadcrumb separator=">">
            <el-breadcrumb-item v-for="item in categoryPath" :key="item.id">
              {{ item.name }}
            </el-breadcrumb-item>
          </el-breadcrumb>
        </div>

        <div v-if="selectedCategory.children && selectedCategory.children.length > 0" class="sub-categories">
          <h4>子分类</h4>
          <el-table :data="selectedCategory.children" stripe>
            <el-table-column prop="name" label="名称" />
            <el-table-column prop="code" label="代码" />
            <el-table-column prop="material_count" label="物料数量" />
            <el-table-column prop="is_active" label="状态">
              <template #default="{ row }">
                <el-tag :type="row.is_active ? 'success' : 'danger'">
                  {{ row.is_active ? '启用' : '禁用' }}
                </el-tag>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </el-dialog>

    <!-- 批量排序对话框 -->
    <el-dialog v-model="showSortDialog" title="批量排序" width="600px">
      <div class="sort-container">
        <el-table :data="sortCategories" stripe>
          <el-table-column prop="name" label="分类名称" />
          <el-table-column prop="code" label="分类代码" />
          <el-table-column label="排序" width="120">
            <template #default="{ row, $index }">
              <el-input-number v-model="row.sort_order" :min="0" size="small" />
            </template>
          </el-table-column>
          <el-table-column label="操作" width="100">
            <template #default="{ row, $index }">
              <el-button size="small" @click="moveCategoryUp($index)" :disabled="$index === 0">
                <el-icon><ArrowUp /></el-icon>
              </el-button>
              <el-button size="small" @click="moveCategoryDown($index)" :disabled="$index === sortCategories.length - 1">
                <el-icon><ArrowDown /></el-icon>
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <template #footer>
        <el-button @click="showSortDialog = false">取消</el-button>
        <el-button type="primary" @click="saveSortOrder">保存排序</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, h, nextTick } from 'vue'
import { ElMessage, ElMessageBox, ElButton, ElTag, ElIcon } from 'element-plus'
import {
  Plus, Search, Expand, Fold, Edit, Delete, View, Sort,
  ArrowUp, ArrowDown, FolderOpened, Folder
} from '@element-plus/icons-vue'
import {
  materialCategoriesApi,
  type MaterialCategory
} from '@/api'

// 响应式数据
const categories = ref<MaterialCategory[]>([])
const treeData = ref<MaterialCategory[]>([])
const searchText = ref('')
const showActiveOnly = ref(true)
const showCreateDialog = ref(false)
const showDetailDialog = ref(false)
const showSortDialog = ref(false)
const editingCategory = ref<MaterialCategory | null>(null)
const selectedCategory = ref<MaterialCategory | null>(null)
const categoryPath = ref<MaterialCategory[]>([])
const codeCheckResult = ref<{ isUnique: boolean } | null>(null)
const categoryTreeRef = ref()

// 统计数据
const stats = ref({
  total_categories: 0,
  active_categories: 0,
  max_level: 0,
  categories_with_materials: 0
})

// 排序相关
const sortCategories = ref<MaterialCategory[]>([])

// 表单数据
const categoryForm = reactive({
  name: '',
  code: '',
  parent_id: null,
  level: 1,
  sort_order: 0,
  description: '',
  is_active: true
})

// 表单验证规则
const categoryRules = {
  name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }],
  code: [
    { required: true, message: '请输入分类代码', trigger: 'blur' },
    { pattern: /^[A-Z0-9_]+$/, message: '代码只能包含大写字母、数字和下划线', trigger: 'blur' }
  ]
}

// 树形组件属性
const treeProps = {
  children: 'children',
  label: 'name'
}

const treeSelectProps = {
  children: 'children',
  label: 'name',
  value: 'id'
}

// 计算属性
const filteredTreeData = computed(() => {
  let result = treeData.value
  
  if (showActiveOnly.value) {
    result = filterActiveCategories(result)
  }
  
  if (searchText.value) {
    result = filterBySearch(result, searchText.value)
  }
  
  return result
})

const parentSelectData = computed(() => {
  // 编辑时排除自己和子级
  if (editingCategory.value) {
    return filterParentOptions(treeData.value, editingCategory.value.id)
  }
  return treeData.value
})

// 方法
const loadCategories = async () => {
  try {
    const response = await materialCategoriesApi.getMaterialCategoryTree()
    // 后端返回的数据结构是 { code: 200, message: '获取成功', data: [...] }
    treeData.value = response.data.data || response.data
    
    // 同时加载平铺数据用于统计
    const flatResponse = await materialCategoriesApi.getMaterialCategories()
    // 后端返回的数据结构是 { code: 200, message: '获取成功', data: { categories: [...] } }
    categories.value = flatResponse.data.data?.categories || flatResponse.data.categories || flatResponse.data
    
    updateStats()
  } catch (error) {
    ElMessage.error('加载分类数据失败')
  }
}

const loadStats = async () => {
  try {
    const response = await materialCategoriesApi.getCategoryStats()
    // 后端返回的数据结构是 { code: 200, message: '获取成功', data: {...} }
    stats.value = response.data.data || response.data
  } catch (error) {
    console.error('加载统计数据失败', error)
  }
}

const updateStats = () => {
  stats.value = {
    total_categories: categories.value.length,
    active_categories: categories.value.filter(c => c.is_active).length,
    max_level: Math.max(...categories.value.map(c => c.level), 0),
    categories_with_materials: categories.value.filter(c => (c.material_count || 0) > 0).length
  }
}

const filterActiveCategories = (data: MaterialCategory[]): MaterialCategory[] => {
  return data.filter(item => {
    if (!item.is_active) return false
    if (item.children) {
      item.children = filterActiveCategories(item.children)
    }
    return true
  })
}

const filterBySearch = (data: MaterialCategory[], search: string): MaterialCategory[] => {
  const result: MaterialCategory[] = []
  
  data.forEach(item => {
    const matches = item.name.toLowerCase().includes(search.toLowerCase()) ||
                   item.code.toLowerCase().includes(search.toLowerCase())
    
    let childMatches: MaterialCategory[] = []
    if (item.children) {
      childMatches = filterBySearch(item.children, search)
    }
    
    if (matches || childMatches.length > 0) {
      result.push({
        ...item,
        children: childMatches
      })
    }
  })
  
  return result
}

const filterParentOptions = (data: MaterialCategory[], excludeId: number): MaterialCategory[] => {
  return data.filter(item => {
    if (item.id === excludeId) return false
    if (item.children) {
      item.children = filterParentOptions(item.children, excludeId)
    }
    return true
  })
}

const handleSearch = () => {
  // 搜索逻辑已在计算属性中处理
}

const expandAll = () => {
  const keys = getAllNodeKeys(treeData.value)
  categoryTreeRef.value?.setExpandedKeys(keys)
}

const collapseAll = () => {
  categoryTreeRef.value?.setExpandedKeys([])
}

const getAllNodeKeys = (data: MaterialCategory[]): number[] => {
  const keys: number[] = []
  data.forEach(item => {
    keys.push(item.id)
    if (item.children) {
      keys.push(...getAllNodeKeys(item.children))
    }
  })
  return keys
}

const renderTreeNode = (h: any, { node, data }: any) => {
  return h('div', { class: 'category-node' }, [
    h('div', { class: 'node-content' }, [
      h(ElIcon, { class: 'node-icon' }, () => 
        data.children && data.children.length > 0 ? h(FolderOpened) : h(Folder)
      ),
      h('span', { class: 'node-label' }, [
        h('strong', data.name),
        h('span', { class: 'node-code' }, ` (${data.code})`),
        h(ElTag, { 
          size: 'small', 
          type: data.is_active ? 'success' : 'danger',
          style: 'margin-left: 8px'
        }, () => data.is_active ? '启用' : '禁用'),
        data.material_count > 0 && h(ElTag, {
          size: 'small',
          type: 'info',
          style: 'margin-left: 4px'
        }, () => `${data.material_count}个物料`)
      ])
    ]),
    h('div', { class: 'node-actions' }, [
      h(ElButton, {
        size: 'small',
        type: 'primary',
        onClick: (e: Event) => {
          e.stopPropagation()
          viewCategory(data)
        }
      }, () => [h(ElIcon, () => h(View)), '详情']),
      h(ElButton, {
        size: 'small',
        onClick: (e: Event) => {
          e.stopPropagation()
          editCategory(data)
        }
      }, () => [h(ElIcon, () => h(Edit)), '编辑']),
      h(ElButton, {
        size: 'small',
        onClick: (e: Event) => {
          e.stopPropagation()
          addSubCategory(data)
        }
      }, () => [h(ElIcon, () => h(Plus)), '添加子级']),
      h(ElButton, {
        size: 'small',
        type: 'danger',
        onClick: (e: Event) => {
          e.stopPropagation()
          deleteCategory(data)
        }
      }, () => [h(ElIcon, () => h(Delete)), '删除'])
    ])
  ])
}

const viewCategory = async (category: MaterialCategory) => {
  selectedCategory.value = category
  
  // 加载分类路径
  try {
    const response = await materialCategoriesApi.getCategoryPath(category.id)
    categoryPath.value = response.data
  } catch (error) {
    console.error('加载分类路径失败', error)
    categoryPath.value = [category]
  }
  
  showDetailDialog.value = true
}

const editCategory = (category: MaterialCategory) => {
  editingCategory.value = category
  Object.assign(categoryForm, {
    ...category,
    parent_id: category.parent?.id || null
  })
  showCreateDialog.value = true
}

const addSubCategory = (parentCategory: MaterialCategory) => {
  editingCategory.value = null
  Object.assign(categoryForm, {
    name: '',
    code: '',
    parent_id: parentCategory.id,
    level: parentCategory.level + 1,
    sort_order: 0,
    description: '',
    is_active: true
  })
  showCreateDialog.value = true
}

const deleteCategory = async (category: MaterialCategory) => {
  try {
    if (category.material_count && category.material_count > 0) {
      ElMessage.warning('该分类下还有物料，无法删除')
      return
    }
    
    if (category.children && category.children.length > 0) {
      ElMessage.warning('该分类下还有子分类，无法删除')
      return
    }
    
    await ElMessageBox.confirm('确定要删除这个分类吗？', '确认删除', {
      type: 'warning'
    })
    
    await materialCategoriesApi.deleteMaterialCategory(category.id)
    ElMessage.success('删除成功')
    loadCategories()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

const checkCodeUnique = async () => {
  if (!categoryForm.code) {
    codeCheckResult.value = null
    return
  }
  
  try {
    const response = await materialCategoriesApi.checkCategoryCode(
      categoryForm.code,
      editingCategory.value?.id
    )
    codeCheckResult.value = response.data
  } catch (error) {
    console.error('检查代码唯一性失败', error)
  }
}

const saveCategory = async () => {
  try {
    if (editingCategory.value) {
      await materialCategoriesApi.updateMaterialCategory(editingCategory.value.id, categoryForm)
      ElMessage.success('更新成功')
    } else {
      await materialCategoriesApi.createMaterialCategory(categoryForm)
      ElMessage.success('创建成功')
    }
    
    showCreateDialog.value = false
    editingCategory.value = null
    resetCategoryForm()
    loadCategories()
  } catch (error) {
    ElMessage.error('保存失败')
  }
}

const resetCategoryForm = () => {
  Object.assign(categoryForm, {
    name: '',
    code: '',
    parent_id: null,
    level: 1,
    sort_order: 0,
    description: '',
    is_active: true
  })
  codeCheckResult.value = null
}

const handleNodeDrop = async (draggingNode: any, dropNode: any, dropType: string) => {
  try {
    const dragData = draggingNode.data
    const dropData = dropNode.data
    
    let newParentId: number | null = null
    
    if (dropType === 'inner') {
      newParentId = dropData.id
    } else {
      newParentId = dropData.parent?.id || null
    }
    
    await materialCategoriesApi.moveMaterialCategory(dragData.id, newParentId)
    ElMessage.success('移动成功')
    loadCategories()
  } catch (error) {
    ElMessage.error('移动失败')
    loadCategories() // 重新加载以恢复原状态
  }
}

const allowDrop = (draggingNode: any, dropNode: any, type: string) => {
  // 不允许拖拽到自己的子节点
  return !isDescendant(draggingNode.data, dropNode.data)
}

const allowDrag = (draggingNode: any) => {
  // 所有节点都允许拖拽
  return true
}

const isDescendant = (ancestor: MaterialCategory, node: MaterialCategory): boolean => {
  if (ancestor.id === node.id) return true
  if (!ancestor.children) return false
  
  return ancestor.children.some(child => isDescendant(child, node))
}

const moveCategoryUp = (index: number) => {
  if (index > 0) {
    const temp = sortCategories.value[index]
    sortCategories.value[index] = sortCategories.value[index - 1]
    sortCategories.value[index - 1] = temp
    
    // 更新排序值
    sortCategories.value.forEach((cat, idx) => {
      cat.sort_order = idx
    })
  }
}

const moveCategoryDown = (index: number) => {
  if (index < sortCategories.value.length - 1) {
    const temp = sortCategories.value[index]
    sortCategories.value[index] = sortCategories.value[index + 1]
    sortCategories.value[index + 1] = temp
    
    // 更新排序值
    sortCategories.value.forEach((cat, idx) => {
      cat.sort_order = idx
    })
  }
}

const saveSortOrder = async () => {
  try {
    const updates = sortCategories.value.map((cat, index) => ({
      id: cat.id,
      sort_order: index
    }))
    
    await materialCategoriesApi.updateCategoriesOrder(updates)
    ElMessage.success('排序保存成功')
    showSortDialog.value = false
    loadCategories()
  } catch (error) {
    ElMessage.error('保存排序失败')
  }
}

const formatDate = (dateString: string) => {
  return new Date(dateString).toLocaleString('zh-CN')
}

// 生命周期
onMounted(() => {
  loadCategories()
  loadStats()
})
</script>

<style scoped>
.material-category {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.page-header h1 {
  margin: 0;
  font-size: 24px;
  color: #303133;
}

.category-container {
  background: white;
  border-radius: 8px;
  padding: 20px;
}

.category-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #ebeef5;
}

.search-section {
  display: flex;
  align-items: center;
}

.stats-section {
  display: flex;
  gap: 30px;
}

.category-tree {
  margin-top: 20px;
}

/* 修复树形组件布局问题 */
.category-tree :deep(.el-tree-node__content) {
  height: auto !important;
  min-height: 40px;
  padding: 8px 0;
  position: relative;
}

.category-tree :deep(.el-tree-node) {
  white-space: normal;
}

.category-node {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 5px 0;
  min-height: 40px;
  position: relative;
  z-index: 1;
}

.node-content {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.node-icon {
  margin-right: 8px;
  color: #409eff;
  flex-shrink: 0;
}

.node-label {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  min-width: 0;
}

.node-code {
  color: #909399;
  font-size: 12px;
  white-space: nowrap;
}

.node-actions {
  display: flex;
  gap: 5px;
  opacity: 0;
  transition: opacity 0.3s;
  flex-shrink: 0;
  margin-left: 10px;
}

.category-node:hover .node-actions {
  opacity: 1;
}

.category-detail {
  margin-top: 10px;
}

.category-path {
  margin-top: 20px;
}

.category-path h4 {
  margin-bottom: 10px;
  color: #409eff;
}

.sub-categories {
  margin-top: 20px;
}

.sub-categories h4 {
  margin-bottom: 10px;
  color: #409eff;
}

.code-check-result {
  margin-top: 5px;
  font-size: 12px;
}

.sort-container {
  margin-top: 10px;
}
</style>